package com.rnkrsoft.suyan.config.server.ajax.executor;


import com.rnkrsoft.suyan.config.server.ajax.config.AjaxConfig;
import lombok.extern.slf4j.Slf4j;

import javax.doc.DocScanner;
import javax.doc.InterfaceInfo;
import javax.doc.data.IRequest;
import javax.doc.data.IResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 用于执行JVM中的接口
 */
@Slf4j
class LocalAjaxExecutor extends AbstractAjaxExecutor implements AjaxExecutor {

    static final Map<String, Object> SERVICE_INSTANCE_CACHE = new ConcurrentHashMap<String, Object>();

    public LocalAjaxExecutor(AjaxConfig ajaxConfig) {
        super(ajaxConfig);
    }

    @Override
    protected IResponse run(InterfaceInfo interfaceInfo, IRequest request) throws Exception{
        try {
            Class requestClass = Class.forName(interfaceInfo.getRequestClassName());
            Class serviceImplClass = Class.forName(interfaceInfo.getServiceInfo().getServiceClassName() + "Impl");
            Method method = serviceImplClass.getMethod(interfaceInfo.getMethodName(), requestClass);
            Object service = SERVICE_INSTANCE_CACHE.get(interfaceInfo.getServiceInfo().getServiceClassName());
            if (service == null) {
                service = serviceImplClass.newInstance();
                SERVICE_INSTANCE_CACHE.put(interfaceInfo.getServiceInfo().getServiceClassName(), service);
            }
            IResponse response = (IResponse) method.invoke(service, request);
            return response;
        } catch (InstantiationException e) {
            log.error("happens unknown error!", e);
        } catch (InvocationTargetException e) {
            Throwable ex = e.getTargetException();
            log.error("call service '" + interfaceInfo.getFullName() +  "' happens error!!" , ex);
        } catch (NoSuchMethodException e) {
            log.error("happens unknown error!", e);
        } catch (IllegalAccessException e) {
            log.error("happens unknown error!", e);
        } catch (ClassNotFoundException e) {
            log.error("happens unknown error!", e);
        } catch (Exception e) {
            log.error("happens unknown error!", e);
        }
        return null;
    }

    @Override
    public ExecutorType getType() {
        return ExecutorType.LOCAL;
    }
}
